package com.cl.utils;

import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

 

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource;

public class ConnectionPool{
	
	 
	private ComboPooledDataSource ds;
	private AbstractPoolBackedDataSource apbds;
	private static ConnectionPool instance;
	private  Properties dbProps = new Properties();
	
	private ConnectionPool(){
		initC3p0();
	} 
		
	/**
	 * 获取唯一实例  线程安全
	 */
	public static synchronized ConnectionPool getInstance(){
		if(instance==null){
			instance = new ConnectionPool();
		}
		return instance;
	} 
	
	/**
	 * 初始化c3p0配置
	 */
	private void initC3p0() {
        try {
            //InputStream is = new FileInputStream(configFile);
        	InputStream is = ConnectionPool.class.getClassLoader().getResourceAsStream("config.properties");
            dbProps.load(is);
           
        } catch (Exception e) {
            e.printStackTrace();
           
            throw new RuntimeException("DB config load failed.");
        }
        ds = new ComboPooledDataSource();
        try {
            ds.setDriverClass(dbProps.getProperty("db.driverClassName").trim());
        } catch (PropertyVetoException e1) {
            throw new RuntimeException("com.mysql.jdbc.Driver加载失败");
        }
        ds.setJdbcUrl(dbProps.getProperty("db.url").trim());
        ds.setUser(dbProps.getProperty("db.username").trim());
        ds.setPassword(dbProps.getProperty("db.password").trim());
        // 连接关闭时默认将所有未提交的操作回滚。Default: false autoCommitOnClose
        ds.setAutoCommitOnClose(true);
        // 定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意：
        // 测试的表必须在初始数据源的时候就存在。Default: null preferredTestQuery
        ds.setPreferredTestQuery("select 1 from dual");
        // 因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
        // 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
        // 等方法来提升连接测试的性能。Default: false testConnectionOnCheckout
        ds.setTestConnectionOnCheckout(false);
        // 如果设为true那么在取得连接的同时将校验连接的有效性。Default: false testConnectionOnCheckin
        ds.setTestConnectionOnCheckin(false);
        // 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
        // 保留，并在下次调用getConnection()的时候继续尝试获取连接。如果设为true，那么在尝试
        // 获取连接失败后该数据源将申明已断开并永久关闭。Default: false breakAfterAcquireFailure
        ds.setBreakAfterAcquireFailure(false);
        try {
            // 初始化时获取三个连接，取值应在minPoolSize与maxPoolSize之间。Default: 3
            ds.setMaxStatements(Integer.parseInt(dbProps.getProperty("db.maxStatements").trim()));

            // 连接池中保留的最大连接数。Default: 15 maxPoolSize
            ds.setMaxPoolSize(Integer.parseInt(dbProps.getProperty("db.maxPoolSize").trim()));

            // 连接池中保留的最小连接数。
            ds.setMinPoolSize(Integer.parseInt(dbProps.getProperty("db.minPoolSize").trim()));

            // 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 acquireIncrement
            ds.setAcquireIncrement(Integer.parseInt(dbProps.getProperty("db.acquireIncrement").trim()));

            // 每60秒检查所有连接池中的空闲连接。Default: 0 idleConnectionTestPeriod
            ds.setIdleConnectionTestPeriod(Integer.parseInt(dbProps.getProperty("db.idleConnectionTestPeriod").trim()));

            // 最大空闲时间,25000秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 maxIdleTime
            ds.setMaxIdleTime(Integer.parseInt(dbProps.getProperty("db.maxIdleTime").trim()));

            // 定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 acquireRetryAttempts
            ds.setAcquireRetryAttempts(Integer.parseInt(dbProps.getProperty("db.acquireRetryAttempts").trim()));

            // 两次连接中间隔时间，单位毫秒。Default: 1000 acquireRetryDelay
           // ds.setAcquireRetryDelay(Integer.parseInt(dbProps.getProperty("c3p0.acquireRetryDelay").trim()));

            
        } catch (Exception e) {
             
            e.printStackTrace();
        }
    }
	

	/**
	 * 获取数据库的类型
	 * @param latnId
	 * @return
	 */
	public String  getDbType(){
		String type = dbProps.getProperty("db.DbType");
		return type;
	}
	
	/**
	 * 获取连接池连接
	 */
	public Connection getConnection() {
		Connection conn = null;
        try {
        	conn = ds.getConnection();
        } catch (SQLException e) {
          e.printStackTrace();
        }
	    return conn;
	}

	/**
	  * 释放连接
	  * @param latnId
	  * @param con
	  */
	public static void freeConnection(Connection conn) {
		if(null != conn){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	 
	
}
 